home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Games / JST / sources / OSEmu / dos.s < prev    next >
Encoding:
Text File  |  2001-03-19  |  38.1 KB  |  2,024 lines

  1. ;APS00000000000000000000000000000000000000000000000000000000000000000000000000000000
  2. * $Id: dos.s 1.1 1999/02/03 04:09:58 jotd Exp $
  3. **************************************************************************
  4. *   DOS-LIBRARY                                                          *
  5. **************************************************************************
  6.  
  7. ; structure for custom filehandle
  8.  
  9. FH_ALLOCLEN = 0
  10. FH_PORT = 4        ; exact DOS offset in FileHandle structure
  11. FH_TYPE = 8        ; exact DOS offset in FileHandle structure
  12. FH_OPENMODE = $C
  13. FH_CURRENTPOS = $10    ; exact DOS offset in FileHandle structure
  14. FH_FILELEN = $14    ; exact DOS offset in FileHandle structure
  15. FH_WRITEBUFPTR = $18    ; buffer pointer
  16. FH_WRITEBUFPOS = $1C    ; current buffer position
  17. FH_WRITEBUFLEN = $20    ; total length of buffer, $1000
  18. FH_WRITESTARTPOS = $24    ; the file offset which corresponds to start of write buffer
  19. FH_DIRLISTSTART = $28    ; for directories, pointer on first item
  20. FH_FILENAME = $2C
  21.  
  22.  
  23. DEFAULT_WRITE_BUFSIZE = 2000    ; default 2ko bufferization for _Write
  24.  
  25. OUTPUT_HANDLER_MAGIC = $DEAF1111
  26.  
  27. BPTR2APTR:MACRO
  28.     add.l    \1,\1
  29.     add.l    \1,\1
  30.     ENDM
  31.  
  32. APTR2BPTR:MACRO
  33.     lsr.l    #2,\1
  34.     ENDM
  35.  
  36. DOSRTS:MACRO
  37.     move.l    D0,D1
  38.     rts
  39.     ENDM
  40.  
  41. **************************************************************************
  42. *   INITIALIZING                                                         *
  43. **************************************************************************
  44.  
  45. DOSINIT        move.l    _dosbase,d0
  46.         beq    .init
  47.         rts
  48.  
  49. .init        move.l    #1050,d0    ;(reserved function)
  50.         move.l    #$46,d1
  51.         lea    _dosname,a0
  52.         bsr    _InitLibrary
  53.         move.l    d0,a0
  54.         move.l    d0,_dosbase
  55.         
  56.         patch    _LVOParentDir(a0),_ParentDir    ; requested by BS
  57.         patch    _LVOLoadSeg(a0),_LoadSeg
  58.         patch    _LVOUnLoadSeg(a0),DOSUNLOADSEG
  59.         patch    _LVOOpen(a0),_Open        ; patched to BCPL
  60.         patch    _LVOOpenFromLock(a0),_OpenFromLock    ; patched to BCPL
  61.         patch    _LVOClose(a0),_Close        ; patched to BCPL
  62.         patch    _LVORead(a0),_Read        ; patched to BCPL
  63.         patch    _LVOWrite(a0),_Write        ; patched to BCPL
  64.         patch    _LVOSeek(a0),_Seek        ; patched to BCPL
  65.         patch    _LVOLock(A0),_Lock        ; patched to BCPL
  66.         patch    _LVOInput(A0),MYRTZ
  67.         patch    _LVODeleteFile(A0),_DeleteFile
  68.         patch    _LVOOutput(A0),_Output
  69.         patch    _LVODeviceProc(A0),MYRTZ
  70.         patch    _LVOGetProgramDir(A0),_GetProgramDir    ; added by JOTD
  71.         patch    _LVOExamine(A0),_Examine    ; patched to BCPL
  72.         patch    _LVOExNext(A0),_ExNext        ; added by JOTD, patched to BCPL
  73.         patch    _LVOExamineFH(A0),_ExamineFH    ; added by JOTD, patched to BCPL
  74.         patch    _LVOSetIoErr(A0),_SetIoErr    ; added by JOTD
  75.         patch    _LVOIoErr(A0),_IoErr        ; added by JOTD
  76.         patch    _LVOUnLock(A0),_UnLock    ; patched to BCPL
  77.         patch    _LVOInfo(A0),_Info
  78.         patch    _LVODupLock(A0),_DupLock    ; patched to BCPL
  79.  
  80.         patch    _LVOIsInteractive(A0),_IsInteractive    ; JOTD
  81.         patch    _LVOCheckSignal(A0),MYRTZ    ; JOTD, dummy
  82.         patch    _LVOWaitForChar(A0),MYRTZ
  83.         patch    _LVOCurrentDir(A0),_CurrentDir
  84.         patch    _LVODelay(A0),_Delay    ; added by JOTD
  85.         patch    _LVODateStamp(A0),DATESTAMP    ; added by JOTD
  86.         patch    _LVOAssignPath(a0),ASSIGNPATH    ; dummy
  87.         patch    _LVOAssignLock(a0),ASSIGNLOCK    ; dummy
  88.         patch    _LVORunCommand(a0),RUNCOMMAND ; added by JOTD
  89.         patch    _LVOExecute(a0),EXECUTE ; added by JOTD
  90.         patch    _LVOGetArgStr(a0),GETARGSTR ; added by JOTD
  91.         patch    _LVOCreateProc(a0),CREATEPROC ; added by JOTD
  92.     
  93. ; init rootnode
  94.         move.l    #_ROOTNODE,dl_Root(A0)
  95.         rts
  96.  
  97. _ROOTNODE:
  98.     dc.l    $EEEEEE01
  99.     dc.l    $EEEEEE02
  100.     dc.l    $0        ; datestamp
  101.     dc.l    $0
  102.     dc.l    $0
  103.     dc.l    $EEEEEE03
  104. _bcplcorrect6:            ; corrected by exec init
  105.     dc.l    _DEFAULT_DOSINFO
  106.     dc.l    $EEEEEE04
  107.     dc.l    $EEEEEE05
  108.     dc.l    $EEEEEE06
  109.     dc.l    $EEEEEE07
  110.     dc.l    $EEEEEE08
  111.     dc.l    $EEEEEE09
  112.     dc.l    $EEEEEE0A    ; to be continued...
  113.  
  114.     CNOP    0,4
  115.  
  116. _DEFAULT_DOSINFO:
  117.     dc.l    $EEEEFFEE    ; private
  118. _bcplcorrect7:
  119.     dc.l    _DEVLIST    ; device list
  120.     dc.l    0        ; leave to zero
  121.     dc.l    0        ; leave to zero
  122.  
  123.     CNOP    0,4
  124.  
  125. _DEVLIST:
  126.     dc.l    0
  127.     dc.l    0
  128.     dc.l    0
  129.     dc.l    0
  130.     dc.l    $EEEEEEEE    ; normally BCPL pointer on BSTR "L:FastFileSystem"
  131.     dc.l    1000        ; stack size
  132.     dc.l    5        ; priority
  133.     dc.l    0        ; startup
  134.     dc.l    $EEEEEE11
  135.     dc.l    $EEEEEE12
  136. _bcplcorrect8:
  137.     dc.l    _DEVNAME
  138.  
  139.     CNOP    0,4
  140. _DEVNAME:
  141.     dc.b    3,"DH0",0        ; BSTR on device name + NULL termination
  142.     CNOP    0,4
  143.  
  144.  
  145. **************************************************************************
  146. *   PROGRAM EXECUTION                                                    *
  147. **************************************************************************
  148.  
  149. ;<D1:NAME
  150. ;<D2:PRIORITY
  151. ;<D3:SEGLIST
  152. ;<D4:STACKSIZE
  153. ; this function never returns
  154. ;
  155. ; ATM this function is designed to handle
  156. ; autodetachable code, not for managing multiple tasks!!
  157.  
  158. CREATEPROC:
  159.     move.l    #0,_EXECLIBTASK+172    ; now we're in the child process
  160.  
  161.     move.l    D4,D0
  162.     move.l    #MEMF_CLEAR,D1
  163.     bsr    ForeignAllocMem
  164.     tst.l    D0
  165.     beq    .cpfail        ; not enough mem for stack
  166.  
  167.     move.l    D0,A7
  168.     add.l    D4,A7        ; sets new stack pointer
  169.  
  170.     LSL.L    #2,D3        ; BCPL -> normal pointer
  171.     MOVE.L    D3,A1
  172.     ADDQ.L    #4,A1
  173.  
  174.     moveq.l    #0,D0    ; I don't know why I'm doing this
  175.     jmp    (A1)    ; executes the program
  176.  
  177. .cpfail        pea    _LVOCreateProc
  178.         pea    _dosname
  179.         bra    _emufail
  180.  
  181. ; EXECUTE
  182. ; <D1: program name
  183. ; <D2: input handler
  184. ; <D3: output handler
  185. ; >D0: success
  186.  
  187. EXECUTE:
  188.     move.l    D1,A0
  189.     lea    .command(pc),A1
  190. .copy
  191.     ; copy name until end or space
  192.     move.b    (A0)+,D0
  193.     cmp.b    #' ',D0
  194.     bne.b    .skipspc
  195.     moveq.l    #0,D0
  196. .skipspc
  197.     move.b    D0,(A1)+
  198.     bne.b    .copy
  199.  
  200.     ; now arguments
  201.  
  202.     lea    .args(pc),A0
  203.  
  204.     tst.b    (-1,A1)
  205.     beq.b    .lf
  206.  
  207. .argcp
  208.     move.b    (A1)+,(A0)+
  209.     bne.b    .argcp
  210.  
  211. .lf
  212.     move.b    #10,(A0)+    ; adds linefeed
  213.     clr.b    (A0)
  214.  
  215.     lea    .command(pc),A1
  216.     move.l    A1,D1    
  217.     JSRLIB    LoadSeg
  218.     tst.l    D0
  219.     beq.b    .err
  220.  
  221.     LSL.L    #2,D0
  222.     MOVE.L    D0,A1
  223.     ADDQ.L    #4,A1
  224.  
  225.     lea    .args(pc),A0
  226.     moveq.l    #0,D0
  227. .count
  228.     tst.b    (A0,D0.W)
  229.     beq.b    .exe
  230.     addq.l    #1,D0
  231.     bra.b    .count
  232.  
  233. .exe
  234.     JSR    (A1)
  235.     moveq.l    #DOSTRUE,D0    ; success
  236.     DOSRTS
  237. .err
  238.     moveq.l    #0,D0
  239.     DOSRTS
  240.  
  241. .command:
  242.     blk.b    $30,0    
  243. .args:
  244.     blk.b    $40,0
  245.  
  246. ;<D1:SEGLIST
  247. ;<D2:STACKSIZE
  248. ;<D3:ARGPTR
  249. ;<D4:ARGSIZE
  250.  
  251. ;RUNCOMMAND will ignore STACKSIZE: it will use the current stack
  252.  
  253. RUNCOMMAND:
  254.     move.l    D3,args_ptr
  255. ;;    move.l    D4,D0
  256.  
  257.     LSL.L    #2,D1
  258.     MOVE.L    D1,A1
  259.     ADDQ.L    #4,A1
  260.  
  261.     jmp    (A1)    ; executes the program
  262.  
  263. GETARGSTR:
  264.     move.l    args_ptr(pc),D0
  265.     RTS
  266.  
  267. args_ptr:
  268.     dc.l    0
  269.  
  270. _SetIoErr:
  271.     move.l    D1,last_io_error
  272.     DOSRTS
  273.  
  274. _IoErr:
  275.     move.l    last_io_error(pc),D0
  276.     DOSRTS
  277.  
  278. last_io_error:
  279.     dc.l    0
  280.  
  281. ; ******************************************
  282. ; 2 special macros added by JOTD for LoadSeg
  283.  
  284. ; calls EnterDebugger when a condition is reached:
  285.  
  286. BREAK_ON_COND:MACRO
  287.     cmp.l    \1,\2
  288.     bne.b    .ok\@
  289.     bsr    EnterDebugger
  290.     nop
  291.     nop
  292. .ok\@
  293.     ENDM
  294.  
  295. ; branch with call to EnterDebugger when true
  296. ; (to trap error code source)
  297.  
  298. ; uncomment to activate
  299.  
  300. ;BRANCH_COND:MACRO
  301. ;    \1    .sk\@
  302. ;    bra.b    .end\@
  303. ;.sk\@
  304. ;    bsr    EnterDebugger
  305. ;    bra    \2
  306. ;.end\@
  307. ;    ENDM
  308.  
  309. BRANCH_COND:MACRO
  310.     \1    \2    ; this is the non-debug configuration
  311.     ENDM
  312.  
  313. ;<D1: filename
  314. ;>D0: return code
  315.  
  316. _DeleteFile:
  317.     move.l    D1,A0
  318.     bsr    SetCurrentDir
  319.     move.l    (_RESLOAD),a1
  320.     jsr    (resload_DeleteFile,a1)
  321.     move.l    D1,last_io_error        ; stores error code
  322.     DOSRTS
  323.  
  324. ;>D1:FILENAME
  325. ;<D0:FIRST SEGMENT
  326. ;INTERNAL: D7-TOTAL # OF SEGMENTS
  327. ;    D6-FILEHANDLE
  328. ;    D5-SEGMENTBASE
  329. ;    A4-8 BYTES SPACE ON STACK FOR HUNKHEADERS+other space for hunk overlay stuff
  330. ;LIMITATIONS: ONLY FOLLOWING HUNKS ALLOWED: HUNK_CODE, HUNK_DATA, HUNK_BSS,
  331. ;        HUNK_END, HUNK_RELOC32, HUNK_HEADER, HUNK_DEBUG, HUNK_SYMBOL,
  332. ;               HUNK_OVERLAY
  333. ;               CONTACT IF YOU HAVE AN EXE WITH OTHER HUNKS, IM SIMPLY MISSING 
  334. ;        THE EXAMPLES TO IMPLEMENT THEM
  335.  
  336. OVY_OVERLAYTABLE = 8
  337. OVY_HUNKTABLE = 12
  338. MAX_HUNK_NUMBER = 16
  339. LAST_LOADED_HUNK_NUMBER = 20
  340. FIRST_HUNK_NUMBER = 24
  341.  
  342. _LoadSeg:
  343.     MOVEM.L    D2-D7/A2-A5,-(A7)
  344.  
  345.     ; allocates some memory from the stack
  346.  
  347.     SUB.L    #FIRST_HUNK_NUMBER+4,A7
  348.     MOVE.L    A7,A4
  349.  
  350.     CLR.L    (A4)+    ; not overlay ATM
  351.     CLR.L    (A4)+    ; not overlay load ATM
  352.     CLR.L    (A4)+
  353.     CLR.L    (A4)+
  354.     CLR.L    (A4)+
  355.     MOVE.L    A7,A4
  356.  
  357.     tst.l    D1
  358.     bne.b    .normal_call
  359.     ; undocumented LoadSeg() call to load the overlay part
  360.     ; D1: NULL
  361.     ; D2: BPTR on hunk table to complete
  362.     ; D3: filehandle
  363.  
  364.     move.l    D2,(OVY_HUNKTABLE,A4)    ; save hunk table
  365.     move.l    D3,D0
  366.     bra.b    .read_header
  367.     
  368. .normal_call
  369.     move.l    D1,A5        ; save filename
  370.     MOVE.L    #MODE_OLDFILE,D2
  371.     BSR.W    _Open
  372.     TST.L    D0
  373.     BRANCH_COND    BEQ.W,.ERR
  374.  
  375.     ; added by JOTD: copy command name & length
  376.  
  377.     lea    _BCPL_CommandName,A3
  378.     moveq.l    #0,D1
  379. .strcp
  380.     addq.l    #1,D1
  381.     move.b    (A5)+,(A3,D1.W)
  382.     beq.b    .endcp
  383.     bra.b    .strcp
  384. .endcp
  385.     lea    _BCPL_CommandName,A3
  386.     subq.l    #1,D1
  387.     move.b    D1,(A3)            ; store length
  388.     ;
  389.  
  390. .read_header:
  391.     MOVE.L    D0,D6            ; handler
  392.     MOVE.L    D6,D1
  393.     MOVE.L    A4,D2
  394.     MOVEQ.L    #4,D3
  395.     BSR.W    _Read
  396.     TST.L    D0
  397.     BRANCH_COND    BEQ.W,.ERR2
  398.     CMP.L    #$3F3,(A4)        ;FIRST LW=HUNK_HEADER?
  399.     BRANCH_COND    BNE.W,.ERR2
  400.     MOVE.L    D6,D1
  401.     MOVE.L    A4,D2
  402.     MOVEQ.L    #4,D3
  403.     BSR.W    _Read
  404.     TST.L    D0
  405.     BRANCH_COND    BEQ.W,.ERR2
  406.     TST.L    (A4)            ;NO NAME PLEASE (feature removed in OS2.0)
  407.     BRANCH_COND    BNE.W,.ERR2
  408.     MOVE.L    D6,D1
  409.     MOVE.L    A4,D2
  410.     MOVEQ.L    #4,D3
  411.     BSR.W    _Read
  412.     TST.L    D0
  413.     BRANCH_COND    BEQ.W,.ERR2
  414.     MOVE.L    (A4),(MAX_HUNK_NUMBER,A4)    ; highest hunk in file
  415.  
  416.     MOVE.L    D6,D1
  417.     MOVE.L    A4,D2
  418.     MOVEQ.L    #8,D3
  419.     BSR.W    _Read
  420.     TST.L    D0
  421.     BRANCH_COND    BEQ.W,.ERR2
  422.     MOVE.L    (A4),(FIRST_HUNK_NUMBER,A4)        ;0 but for overlays
  423. ;    TST.L    (A4)            ;FIRST HUNK HAS TO BE 0
  424. ;    BRANCH_COND    BNE.W,.ERR2
  425.  
  426.     MOVE.L    4(A4),(LAST_LOADED_HUNK_NUMBER,A4)    ;LAST LOADED HUNK (means: overlay not included)
  427.  
  428. ; loop for all hunks which are to be loaded (don't consider overlays)
  429.  
  430.     move.l    (LAST_LOADED_HUNK_NUMBER,A4),D7
  431.     sub.l    (FIRST_HUNK_NUMBER,A4),D7
  432.  
  433.     MOVEQ.L    #0,D4            ;ALLOC MEM FOR ALL SEGMENTS
  434.     MOVEQ.L    #0,D5
  435. .1
  436.  
  437.     MOVE.L    D6,D1
  438.     MOVE.L    A4,D2
  439.     MOVEQ.L    #4,D3            ;GET SIZE AND MEMFLAGS OF HUNK
  440.     BSR.W    _Read
  441.     TST.L    D0
  442.     BRANCH_COND    BEQ.W,.ERR3
  443.  
  444.     MOVE.L    (A4),D0
  445.  
  446.     ; added by JOTD: check memtype requirement
  447.  
  448.     bsr    .getmemflag    ; >D1: MEMF_xxx
  449.  
  450.     ; compute mem size
  451.  
  452.     LSL.L    #2,D0
  453.     ADDQ.L    #8,D0
  454.     MOVE.L    D0,D2            ;ALLOC MEM IN SIZE
  455.     ADDQ.L    #7,D0
  456.     AND.L    #$FFFFFFF8,D0
  457.     BSR.W    ForeignAllocMem
  458.     TST.L    D0
  459.     BRANCH_COND    BEQ.W,.ERR3
  460.     MOVE.L    D0,A3
  461.     MOVE.L    D2,(A3)
  462.     CLR.L    4(A3)
  463.  
  464.     TST.L    D4
  465.     BNE.S    .2
  466.     MOVE.L    D0,D5            ;D5-POINTER TO 1ST SEGMENT
  467.     BRA.S    .3
  468.  
  469. .2
  470.     MOVE.L    D5,A3            ;POINTER TO 1ST SEGMENT
  471. .5    TST.L    4(A3)
  472.     BEQ.S    .4
  473.     MOVE.L    4(A3),D2        ;NEXT SEGMENT
  474.     LSL.L    #2,D2
  475.     SUBQ.L    #4,D2
  476.     MOVE.L    D2,A3
  477.     BRA.S    .5
  478.  
  479.  
  480. .4    ADDQ.L    #4,D0
  481.     LSR.L    #2,D0
  482.     MOVE.L    D0,4(A3)
  483. .3    ADDQ.L    #1,D4
  484.     CMP.L    D7,D4
  485.     BLS.S    .1            ; next hunk
  486.                     ;HEADER COMPLETE, MEM ALLOCATED
  487.  
  488.     ;NOW PROCESSING THE HUNK_CODE, HUNK_DATA AND HUNK_BSS, HUNK_OVERLAY...
  489.  
  490.     move.l    (MAX_HUNK_NUMBER,A4),D7 ; real hunk count (including overlays)
  491.     sub.l    (FIRST_HUNK_NUMBER,A4),D7    ; remove first hunk offset
  492.     subq.l    #1,D7
  493.     bpl.s    .d7positive
  494.     moveq.l    #0,D7
  495. .d7positive
  496.  
  497.     MOVEQ.L    #0,D4
  498. .HN    MOVE.L    D6,D1
  499.     MOVE.L    A4,D2
  500.     MOVEQ.L    #4,D3            ;GET TYPE OF HUNK
  501.     BSR.W    _Read
  502.     TST.L    D0
  503.     BRANCH_COND    BEQ.W,.ERR3    ;END OF FILE ENCOUNTERED
  504. .MAINHUNKS:
  505.     AND.L    #$3FFFFFFF,(A4)
  506.     CMP.L    #$3E9,(A4)        ;HUNK_CODE?
  507.     BEQ.W    .HCD
  508.     CMP.L    #$3F1,(A4)        ;HUNK_DEBUG?
  509.     BEQ.S    .HDEBUG1
  510.     CMP.L    #$3EA,(A4)        ;HUNK_DATA?
  511.     BEQ.S    .HCD
  512.     CMP.L    #$3EB,(A4)        ;HUNK_BSS?
  513.     BEQ.S    .HBSS
  514.     CMP.L    #$3F5,(A4)        ;HUNK_OVERLAY?
  515.     BEQ.W    .HOVLY
  516.     BRANCH_COND    BRA.W,.ERR3
  517.  
  518.     ; debug hunk support, added by JOTD
  519. .HDEBUG1:
  520.     bsr.s    .HDEBUG
  521.     BRA.W    .HN
  522.  
  523. .HDEBUG2
  524.     bsr.s    .HDEBUG
  525.     bra    .INNERHUNK
  526.     
  527. .HDEBUG:
  528.     MOVE.L    D6,D1
  529.     MOVE.L    A4,D2
  530.     MOVEQ.L    #4,D3
  531.     BSR.W    _Read            ;GET HUNK LENGTH
  532.     MOVE.L    (A4),D0
  533.  
  534.     BPTR2APTR    D0
  535.  
  536.     MOVE.L    D6,D1
  537.     MOVE.L    D0,D2
  538.     MOVE.L    #OFFSET_CURRENT,D3
  539.     BSR.W    _Seek            ;SKIP DEBUG DATA
  540.     CMP.L    #-1,D0            ;error
  541.     BRANCH_COND    BEQ.W,.ERR3
  542.     RTS
  543.  
  544. .HBSS    
  545.     MOVE.L    D6,D1            ;BSS-HUNK
  546.     MOVE.L    A4,D2
  547.     MOVEQ.L    #4,D3            ;IGNORE SIZE OF HUNK
  548.     BSR.W    _Read
  549.     TST.L    D0
  550.     BRANCH_COND    BEQ.W,.ERR3
  551.     BRA.S    .INNERHUNK
  552.  
  553. .HCD
  554.     MOVE.L    D6,D1            ;CODE- AND DATA-HUNK
  555.     MOVE.L    A4,D2
  556.     MOVEQ.L    #4,D3            ;GET SIZE OF HUNK
  557.     BSR.W    _Read
  558.     TST.L    D0
  559.     BRANCH_COND    BEQ.W,.ERR3
  560.     MOVE.L    (A4),D3            ;LEN OF HUNK
  561.     beq    .INNERHUNK        ; added by JOTD, hunk code can be of 0 length
  562.     LSL.L    #2,D3
  563.     MOVE.L    D4,D1            ;ACTUAL HUNK
  564.     MOVE.L    D5,A3            ;START OF 1ST SEGMENT
  565.     BRA.S    .HCD1
  566.  
  567. .HCD2    MOVE.L    4(A3),D2
  568.     LSL.L    #2,D2
  569.     SUBQ.L    #4,D2
  570.     MOVE.L    D2,A3
  571. .HCD1    DBF    D1,.HCD2
  572.     MOVE.L    A3,D2
  573.     ADDQ.L    #8,D2
  574.     MOVE.L    D6,D1
  575.  
  576.     
  577.     move.l    D2,-(A7)    ; save D2
  578.     BSR.W    _Read
  579.     move.l    (A7)+,D2    ; restore D2
  580.     TST.L    D0
  581.     BRANCH_COND    BEQ.W,.ERR3
  582.  
  583.     ; OVERLAY? hunk code loaded:
  584.     ; let's check if it's an overlay manager
  585.  
  586.     move.l    D2,A0
  587.     cmp.w    #$6000,(A0)
  588.     bne.b    .INNERHUNK    ; not an overlay manager
  589.     cmp.l    #$ABCD,(4,A0)
  590.     bne.b    .INNERHUNK    ; not an overlay manager
  591.  
  592.     ; save overlay manager offset
  593.  
  594.     addq.l    #8,A0
  595.     move.l    A0,(OVY_OVERLAYTABLE,A4)
  596.  
  597.     ; END OVERLAY?
  598.     ; continue hunk processing
  599.  
  600. .INNERHUNK:
  601.     MOVE.L    D6,D1
  602.     MOVE.L    A4,D2
  603.     MOVEQ.L    #4,D3            ;GET TYPE OF HUNK
  604.     BSR.W    _Read
  605.     TST.L    D0
  606.     BRANCH_COND    BEQ.W,.ERR3
  607.     CMP.L    #$3EC,(A4)        ;HUNK_RELOC32?
  608.     BEQ.S    .HRELOCT
  609.     CMP.L    #$3F2,(A4)        ;HUNK_END?
  610.     BEQ.W    .HENDT
  611.     CMP.L    #$3F0,(A4)        ;HUNK_SYMBOL?
  612.     BEQ.W    .HSYMBOLT
  613.     CMP.L    #$3F1,(A4)        ;HUNK_DEBUG?
  614.     BEQ.W    .HDEBUG2
  615.     BRANCH_COND    BRA.W,.ERR3
  616.  
  617. .HRELOCT
  618.     MOVE.L    D6,D1
  619.     MOVE.L    A4,D2
  620.     MOVEQ.L    #4,D3            ;GET COUNT OF LW-RELOCS
  621.     BSR.W    _Read
  622.     TST.L    D0
  623.     BRANCH_COND    BEQ.W,.ERR3
  624.     TST.L    (A4)            ;END OF RELOCATION?
  625.     BEQ.S    .INNERHUNK
  626.     MOVE.L    D6,D1
  627.     MOVE.L    A4,D2
  628.     ADDQ.L    #4,D2
  629.     MOVEQ.L    #4,D3            ;GET CORRESPONDING HUNK TO RELOCATE TO
  630.     BSR.W    _Read
  631.     TST.L    D0
  632.     BRANCH_COND    BEQ.W,.ERR3
  633.  
  634.     MOVE.L    (A4),D0
  635.  
  636.     bsr    .getmemflag
  637.  
  638.     LSL.L    #2,D0            ;ALLOC MEM OF SIZE OF RELOCTABLE
  639.     ADDQ.L    #7,D0
  640.     AND.L    #$FFFFFFF8,D0
  641.  
  642.     BSR.W    ForeignAllocMem
  643.     TST.L    D0
  644.     BRANCH_COND    BEQ.W,.ERR4
  645.     MOVE.L    D0,A2
  646.     MOVE.L    D6,D1
  647.     MOVE.L    A2,D2
  648.     MOVE.L    (A4),D3            ;GET CORRESPONDING RELOCS TO RELOCATE
  649.     LSL.L    #2,D3
  650.     BSR.W    _Read
  651.     TST.L    D0
  652.     BRANCH_COND    BEQ.W,.ERR4
  653.     MOVE.L    (A4),D3            ;# OF RELOCS
  654.     MOVE.L    4(A4),D2        ;WHICH HUNK TO RELOCATE TO?
  655.     MOVE.L    D5,A0
  656.     BRA.S    .HRELOCT3
  657.  
  658. .HRELOCT4
  659.     MOVE.L    4(A0),D0
  660.     LSL.L    #2,D0
  661.     SUBQ.L    #4,D0
  662.     MOVE.L    D0,A0
  663. .HRELOCT3
  664.     DBF    D2,.HRELOCT4        
  665.  
  666.     ADDQ.L    #8,A0
  667.     MOVE.L    A0,D0            ;GOT THE HUNK TO RELOCATE TO
  668.     LEA.L    8(A3),A1        ;THIS HUNK WILL BE RELOCATED
  669.     MOVE.L    A2,A0            ;HERE ARE THE RELOCS
  670.     BRA.S    .HRELOCT5
  671.  
  672. .HRELOCT6
  673.     MOVE.L    (A0)+,D1
  674.     ADD.L    D0,(A1,D1.L)
  675. .HRELOCT5
  676.     DBF    D3,.HRELOCT6
  677.     MOVE.L    A2,A1            ;FREE THE MEM OF SIZE OF RELOCTABLE
  678.     MOVE.L    (A4),D0
  679.     LSL.L    #2,D0
  680.     ADDQ.L    #7,D0
  681.     AND.L    #$FFFFFFF8,D0
  682.  
  683.     bsr    ForeignFreeMem
  684.  
  685.     BRA.W    .HRELOCT
  686.  
  687. .HSYMBOLT
  688.     MOVE.L    D6,D1
  689.     MOVE.L    A4,D2
  690.     MOVEQ.L    #4,D3
  691.     BSR.W    _Read            ;GET NAMELENGTH
  692.     TST.L    D0
  693.     BRANCH_COND    BEQ.W,.ERR3
  694.     MOVE.L    (A4),D0
  695.     AND.L    #$FFFFFF,D0
  696.     BEQ.W    .INNERHUNK        ;IF NO NAMELENGTH -> END OF HUNK
  697.     LSL.L    #2,D0            ;LEN OF NAME IS IN LONGWORDS
  698.     ADDQ.L    #4,D0            ;SKIP ALSO SYMBOLOFFSET
  699.     MOVE.L    D6,D1
  700.     MOVE.L    D0,D2
  701.     MOVE.L    #OFFSET_CURRENT,D3
  702.     BSR.W    _Seek
  703.     CMP.L    #-1,D0
  704.     BRANCH_COND    BEQ.W,.ERR3
  705.     BRA.S    .HSYMBOLT
  706.  
  707.     ; overlay hunk support, added by JOTD
  708. .HOVLY:
  709.     ; overlay file detected!
  710.     ; fill in the information needed
  711.  
  712.     ; reads number of longwords - 1
  713.  
  714.     MOVE.L    D6,D1
  715.     MOVE.L    A4,D2
  716.     MOVEQ.L    #4,D3            ;GET TYPE OF HUNK
  717.     BSR.W    _Read
  718.     TST.L    D0
  719.     BRANCH_COND    BEQ.W,.ERR3    ;END OF FILE ENCOUNTERED
  720.     move.l    (A4),D0            ;number of longwords that follow minus one
  721.     addq.l    #1,D0
  722.  
  723. ;    cmp.l    #5,D0            ; too complex: not supported right now
  724. ;    BRANCH_COND    BNE.W,.ERR3
  725.  
  726.     add.l    D0,D0
  727.     add.l    D0,D0
  728.     move.l    D0,D3        ; save size
  729.     moveq.l    #0,D1        ; any memory
  730.     
  731.     move.l    A6,-(A7)
  732.     move.l    $4.W,A6
  733.     JSRLIB    AllocVec
  734.     move.l    (A7)+,A6
  735.  
  736.     move.l    D0,D2        ; buffer
  737.     beq.w    .ERR3
  738.  
  739.     move.l    (OVY_OVERLAYTABLE,A4),A0
  740.     move.l    D6,(A0)        ; stream on executable file
  741.     move.l    D0,(4,A0)    ; overlay table pointer
  742.  
  743.     ; D3: saved size
  744.     move.l    D2,D0
  745.     MOVE.L    D6,D1    ; handler
  746.     BSR.W    _Read            ;LOAD LONGWORDS
  747.  
  748.     move.l    (MAX_HUNK_NUMBER,A4),D0
  749.     addq.l    #1,D0
  750.     add.l    D0,D0
  751.     add.l    D0,D0
  752.     moveq.l    #0,D1        ; any memory
  753.  
  754.     move.l    A6,-(A7)
  755.     move.l    $4.W,A6
  756.     JSRLIB    AllocVec
  757.     move.l    (A7)+,A6
  758.  
  759.     BRANCH_COND    BEQ.W,.ERR3    ;no more mem!
  760.  
  761.     move.l    (OVY_OVERLAYTABLE,A4),A0
  762.     lsr.l    #2,D0
  763.     move.l    D0,(8,A0)    ; hunk table pointer, to fill in the end
  764.     move.l    #-1,($C,A0)    ; invalid GlobalVec (unused by non-BCPL programs)
  765.  
  766.     ; stop file parsing from here, exit, without closing file
  767.  
  768.     bra.b    .END_NOCLOSE
  769.  
  770. .HENDT
  771.     ADDQ.L    #1,D4
  772.     CMP.L    D7,D4
  773.     BLS.W    .HN
  774.  
  775. .END    
  776.     MOVE.L    D6,D1
  777.     BSR.W    _Close
  778. .END_NOCLOSE
  779.     MOVE.L    D5,D0
  780.     ADDQ.L    #4,D0
  781.     MOVE.L    D0,OSM_LASTLOADSEG
  782.     LSR.L    #2,D0
  783.     move.l    D0,LastSegList            ; added by JOTD
  784.     move.l    D0,LastSegList2            ; added by JOTD
  785.  
  786.     move.l    (OVY_HUNKTABLE,A4),A0
  787.     cmp.l    #0,A0
  788.     beq.b    .tryovy
  789.  
  790.     ; just loaded an overlay hunk by the undocumented call to LoadSeg() with D1=0
  791.     ; search for zero
  792.  
  793.     add.l    A0,A0
  794.     add.l    A0,A0
  795. .zsearch
  796.     tst.l    (A0)+
  797.     bne.b    .zsearch
  798. .zfound:
  799.     subq.l    #4,A0
  800.     bra.b    .fillhunktable
  801.  
  802.     ; A0 points now to an empty space to fill in
  803.  
  804. .tryovy:
  805.     move.l    (OVY_OVERLAYTABLE,A4),A0
  806.     cmp.l    #0,A0
  807.     beq.b    .noovy
  808.  
  809.     ; overlay: fill in the list with hunk list
  810.  
  811.     move.l    (8,A0),D5
  812.     add.l    D5,D5
  813.     add.l    D5,D5
  814.     move.l    D5,A0    ; real pointer on seglist
  815. .fillhunktable:
  816.     move.l    D0,D5
  817. .hunkstrloop:    
  818.     move.l    D5,(A0)+
  819.     beq.b    .noovy
  820.     add.l    D5,D5
  821.     add.l    D5,D5    
  822.     move.l    D5,A1
  823.     move.l    (A1),D5
  824.     bra.b    .hunkstrloop
  825.  
  826. .noovy
  827.  
  828.     ADD.L    #FIRST_HUNK_NUMBER+4,A7        ; restores stack
  829.     move.l    (_RESLOAD),a2
  830.     jsr    (resload_FlushCache,a2)        ; added by JOTD: cache flush
  831. .exit
  832.     MOVEM.L    (A7)+,D2-D7/A2-A5
  833.     DOSRTS
  834.  
  835. .ERR4
  836. .ERR3
  837. .ERR2
  838.         pea    _LVOLoadSeg
  839.         pea    _dosname
  840.         bra    _emufail
  841.  
  842. ;    MOVE.L    D6,D1
  843. ;    BSR.W    _Close
  844. .ERR    MOVEQ.L    #0,D0
  845.  
  846.     ADDQ.L    #8,A7
  847.     bra.b    .exit
  848.  
  849. ; utility routines used by LoadSeg()
  850.  
  851. .getmemflag:
  852.     btst    #HUNKB_CHIP,D0            ; CHIPMEM required?
  853.     beq.b    .nochip
  854.  
  855.     move.l    #MEMF_CHIP,D1
  856.     bra.b    .doalloc
  857. .nochip
  858.     btst    #HUNKB_FAST,D0            ; FASTMEM required?
  859.     beq.b    .nofast
  860.  
  861.     move.l    #MEMF_FAST,D1
  862.     bra.b    .doalloc
  863.  
  864. .nofast
  865.     MOVEQ.L    #MEMF_ANY,D1            ;any memtype will do
  866. .doalloc
  867.     bset    #MEMB_CLEAR,D1            ;adds CLEAR flag
  868.     rts
  869.  
  870. ; UnLoadSeg()
  871.  
  872. DOSUNLOADSEG
  873.     MOVE.L    A2,-(A7)
  874.     LSL.L    #2,D1
  875. .1    MOVE.L    D1,A1
  876.     MOVE.L    (A1),D1
  877.     LSL.L    #2,D1
  878.     MOVE.L    D1,A2
  879.  
  880.     SUBQ.L    #4,A1
  881.     MOVE.L    (A1),D0
  882.  
  883.     bsr    ForeignFreeMem
  884.  
  885.     MOVE.L    A2,D1
  886.     BNE.S    .1
  887.  
  888.     MOVEQ.L    #0,D0
  889.     MOVE.L    (A7)+,A2
  890.     DOSRTS
  891.  
  892. **************************************************************************
  893. *   I/O FILE FUNCTIONS                                                   *
  894. **************************************************************************
  895.  
  896. ;will not work properly if the program assigns a subdir
  897. ;I (JOTD) added it for SlamTilt, which only assigns to PROGDIR:
  898. ;so it's OK
  899.  
  900. ASSIGNLOCK:
  901.     moveq.l    #1,D0
  902.     RTS
  903.  
  904. ;will not work properly if the program assigns a subdir
  905. ;I (JOTD) added it for SlamTilt, which only assigns to PROGDIR:
  906. ;so it's OK
  907.  
  908. ASSIGNPATH:
  909.     moveq.l    #1,D0
  910.     RTS
  911.  
  912. ; added by JOTD
  913.  
  914. _GetProgramDir:
  915.     lea    .volname(pc),A1
  916.     move.l    D1,A1
  917.     bsr    _Lock
  918.     RTS
  919. .volname:
  920.     dc.b    "PROGDIR:",0
  921.     even
  922.  
  923.  
  924. ;Note: open strips the device from the filename (avoiding problems with assigns)
  925. ; < D1: filename
  926. ; < D2: openmode
  927. ; > D0: BPTR on filehandle
  928.  
  929. _Open:
  930.     MOVEM.L    D4-D5/A3-A5,-(A7)
  931.     MOVE.L    D1,A3            ; filename
  932.  
  933.     cmp.b    #'*',(A3)
  934.     bne.b    .nocon
  935.     tst.b    (1,A3)
  936.     bne.b    .nocon
  937.     MOVEM.L    (A7)+,D4-D5/A3-A5
  938.     bra    _Output
  939. .nocon
  940.  
  941.     MOVEQ.L    #FH_FILENAME,D4            ;HEADERLEN
  942.     TST.B    (A3)
  943.     BEQ.W    .ERR
  944. .1    ADDQ.L    #1,D4
  945.     TST.B    (A3)+
  946.     BNE.S    .1
  947.     ADDQ.L    #7,D4            ;NEXT $8-BOUNDARY
  948.     AND.L    #$FFFFFFF8,D4
  949.     MOVE.L    D1,D5            ;^NAME
  950.     MOVE.L    D4,D0            ;ALLOC. LENGTH
  951.     MOVE.L    #MEMF_CLEAR,D1        ;mem is better cleared
  952.     BSR.W    ForeignAllocMem
  953.     TST.L    D0
  954.     BEQ.S    .ERR
  955.     MOVE.L    D0,A3
  956.     MOVE.L    D4,FH_ALLOCLEN(A3)            ;ALLOC. LENGTH
  957.     MOVE.L    D2,FH_OPENMODE(A3)        ;OPENMODE
  958.     CLR.L    FH_CURRENTPOS(A3)        ;INFILE-POINTER TO 0
  959.     move.l    #-1,FH_TYPE(A3)            ;regular file
  960.     ; for buffered write
  961.     clr.l    FH_WRITEBUFPTR(A3)
  962.     clr.l    FH_WRITEBUFPOS(A3)
  963.     clr.l    FH_WRITEBUFLEN(A3)
  964.     clr.l    FH_WRITESTARTPOS(A3)
  965.  
  966.     ; JOTD: cleaned up old Harry's devicename strip by calling my routine
  967.  
  968.     move.l    D5,A0
  969.     bsr    SetCurrentDir
  970.     lea    FH_FILENAME(A3),A4
  971. .namecopy
  972.     move.b    (A0)+,(A4)+
  973.     bne.b    .namecopy
  974.  
  975.     CMP.W    #MODE_NEWFILE,D2    ;IF MODE_NEWFILE, DELETE FILE
  976.     BEQ.S    .NEWFILE
  977.  
  978.                     ;CHECK IF FILE EXISTS
  979.     LEA.L    FH_FILENAME(A3),A0        ;filename
  980.     move.l    _RESLOAD(PC),a1
  981.     jsr    (resload_GetFileSize,a1)
  982.     MOVE.L    D0,FH_FILELEN(A3)
  983.     beq.b    .filenotfound
  984.  
  985.     MOVE.L    A3,D0
  986. .END
  987.     APTR2BPTR    D0    ; BCPL conversion (JOTD)
  988.     MOVEM.L    (A7)+,D4-D5/A3-A5
  989.     DOSRTS
  990.  
  991. .filenotfound
  992.     ; sets DOS error code
  993.     move.l    #ERROR_OBJECT_NOT_FOUND,D1
  994.     bsr    _SetIoErr
  995.  
  996.     MOVE.L    A3,A1
  997.     MOVE.L    FH_ALLOCLEN(A1),D0
  998.  
  999.     bsr    ForeignFreeMem
  1000.  
  1001. .ERR    MOVEQ.L    #0,D0
  1002.     BRA.S    .END
  1003.  
  1004. .NEWFILE                ;REDUCE FILE TO 0 BYTE
  1005.     MOVE.L    OSM_WRITE_BUFSIZE,D0
  1006.     MOVE.L    #MEMF_CLEAR,D1
  1007.     BSR    ForeignAllocMem
  1008.  
  1009.     move.l    D0,FH_WRITEBUFPTR(A3)
  1010.     BEQ.B    .NOBUFMEM
  1011.     
  1012.     ; buffered write, added by JOTD
  1013.  
  1014.     clr.l    FH_WRITEBUFPOS(A3)
  1015.     move.l    OSM_WRITE_BUFSIZE,FH_WRITEBUFLEN(A3)
  1016. .NOBUFMEM
  1017.     CLR.L    FH_FILELEN(A3)
  1018.     LEA.L    FH_FILENAME(A3),A0
  1019.     MOVEQ.L    #0,D0
  1020.     LEA.L    $0.W,A1    ; address is not important since we write 0 bytes
  1021.  
  1022.     move.l    _RESLOAD(pc),a5
  1023.     jsr    (resload_SaveFile,a5)
  1024.  
  1025.     tst.l    D0
  1026.     beq.b    .saveok
  1027.  
  1028.     ; cause of the error
  1029.     move.l    #ERROR_WRITE_PROTECTED,D1
  1030.     bsr    _SetIoErr
  1031. .saveok
  1032.  
  1033. .SKIPZFILE
  1034.     MOVE.L    A3,D0
  1035.     BRA.S    .END
  1036.  
  1037. ; fake output routine
  1038.  
  1039. ; < D0: output file handler, actually a magic number
  1040. ;       that Write will recognize
  1041.  
  1042. _Output:
  1043.     move.l    #OUTPUT_HANDLER_MAGIC,D0
  1044.     DOSRTS
  1045.  
  1046.  
  1047. ; < D1: file handler
  1048. ; < D2: destination buffer
  1049. ; < D3: number of bytes to read
  1050. ; > D0: number of bytes read
  1051.  
  1052. _Read:
  1053.     MOVEM.L    D3/A2-A3,-(A7)
  1054.  
  1055.     BPTR2APTR    D1
  1056.  
  1057.     MOVE.L    D1,A3
  1058.     MOVE.L    FH_CURRENTPOS(A3),D1        ;OFFSET (current)
  1059.     MOVE.L    D2,A1            ;DEST
  1060.     LEA.L    FH_FILENAME(A3),A0        ;NAME
  1061.     MOVE.L    FH_FILELEN(A3),D0        ;TOTAL LENGTH OF FILE
  1062.     SUB.L    D1,D0
  1063.     EXG    D3,D0
  1064.     CMP.L    D0,D3            ;CMP REQUESTED/REAL
  1065.     BHI.S    .1            ;IF REQUESTED<=REAL
  1066.     MOVE.L    D3,D0
  1067. .1    MOVE.L    D0,D3
  1068.                     ;LOAD IT
  1069.     MOVE.L    _RESLOAD(PC),A2
  1070.  
  1071.     JSR    resload_LoadFileOffset(A2)
  1072.  
  1073.     ADD.L    D3,FH_CURRENTPOS(A3)
  1074.     MOVE.L    D3,D0
  1075.     MOVEM.L    (A7)+,D3/A2-A3
  1076.     DOSRTS
  1077.  
  1078. ; Write()
  1079. ; <D1: filehandle
  1080. ; <D2: source bytes
  1081. ; <D3: length
  1082. ;
  1083. ; Jeff: added bufferized writes
  1084.  
  1085. _Write:
  1086.     cmp.l    #OUTPUT_HANDLER_MAGIC,D1    ; try to write to output?
  1087.     beq    .fake_output
  1088.  
  1089.     ifeq    1
  1090.  
  1091.     MOVEM.L    D3-D4/A2-A4,-(A7)
  1092.  
  1093.     BPTR2APTR    D1
  1094.  
  1095.     MOVE.L    D1,A3
  1096.     MOVE.L    FH_CURRENTPOS(A3),D1        ;OFFSET
  1097.     MOVE.L    D2,A1                ;SOURCE
  1098.     LEA.L    FH_FILENAME(A3),A0        ;NAME
  1099.     MOVE.L    D3,D0                ;LENGTH
  1100.  
  1101.     tst.l    FH_WRITEBUFPTR(A3)
  1102.     beq.b    .direct_write        ; old write method
  1103.     ; don't write now, but store the data in the buffer
  1104.     ; for later use if we can
  1105.  
  1106.     move.l    FH_WRITEBUFPOS(A3),D4
  1107.     add.l    D0,D4            ; D4=next pos
  1108.  
  1109.     cmp.l    FH_WRITEBUFLEN(A3),D4    ; compare buffer len with len to write
  1110.     bcc.b    .buffer_overflow    ; buffer will not hold all the data
  1111.     
  1112.     ; we don't really write the file here
  1113.     ; just copy it in the buffer
  1114.  
  1115.     tst.l    FH_WRITEBUFPOS(A3)
  1116.     bne.b    .filled
  1117.  
  1118.     ; the buffer is empty: store file offset
  1119.  
  1120.     move.l    FH_CURRENTPOS(A3),FH_WRITESTARTPOS(A3)
  1121. .filled
  1122.     ; ok, do the copy
  1123.  
  1124.     move.l    A1,A2            ; source
  1125.     move.l    FH_WRITEBUFPTR(A3),A4
  1126.     add.l    FH_WRITEBUFPOS(A3),A4    ; destination
  1127.     move.l    D0,D4            ; length
  1128.  
  1129.     ; perform the byte to byte copy
  1130. .copy
  1131.     move.b    (A2)+,(A4)+
  1132.     subq.l    #1,D4
  1133.     bne.b    .copy
  1134.  
  1135.     ; update the buffer position
  1136.  
  1137.     add.l    D0,FH_WRITEBUFPOS(A3)
  1138.  
  1139.     ; goes to end of write
  1140.  
  1141.     bra.b    .end_write
  1142. .buffer_overflow
  1143.     ; buffer overflow. Can be improved
  1144.  
  1145.     ; first update buffer size (D1 holds offset)
  1146.  
  1147. ;    add.l    FH_WRITEBUFPOS(A3),D1    ; update for WHDLoad call
  1148. ;    add.l    FH_WRITEBUFPOS(A3),D3    ; update for size update
  1149.  
  1150.     ; second flush the buffer
  1151.  
  1152.     move.l    A1,-(A7)
  1153.     move.l    A3,A1
  1154.     bsr    FlushWrite
  1155.     move.l    (A7)+,A1
  1156.  
  1157.     ; then, direct write
  1158.  
  1159. .direct_write
  1160.     MOVE.L    _RESLOAD(PC),A2        ;SAVE IT
  1161.     JSR    resload_SaveFileOffset(A2)
  1162. .end_write
  1163.     ADD.L    D3,FH_CURRENTPOS(A3)
  1164.     LEA.L    FH_FILENAME(A3),A0        ;filename
  1165.     move.l    _RESLOAD(PC),a1
  1166.     jsr    (resload_GetFileSize,a1)
  1167.     MOVE.L    D0,FH_FILELEN(A3)
  1168.     MOVE.L    D3,D0
  1169.     MOVEM.L    (A7)+,D3-D4/A2-A4
  1170.     DOSRTS
  1171.     endif
  1172.  
  1173.     ; JOTD: restored old non-bufferized version
  1174.  
  1175.     MOVEM.L    D3-D4/A2-A3,-(A7)
  1176.  
  1177.     BPTR2APTR    D1        ; APTR conversion (JOTD)
  1178.  
  1179.     MOVE.L    D1,A3
  1180.     MOVE.L    FH_CURRENTPOS(A3),D1        ;OFFSET
  1181.     MOVE.L    D2,A1            ;DEST
  1182.     LEA.L    FH_FILENAME(A3),A0        ;NAME
  1183.     MOVE.L    D3,D0
  1184.  
  1185.     MOVE.L    _RESLOAD(PC),A2        ;SAVE IT
  1186.     JSR    resload_SaveFileOffset(A2)
  1187. .SKIPWFILE:
  1188.     ADD.L    D3,FH_CURRENTPOS(A3)
  1189.     LEA.L    FH_FILENAME(A3),A0        ;filename
  1190.     move.l    _RESLOAD(PC),a1
  1191.     jsr    (resload_GetFileSize,a1)
  1192.     MOVE.L    D0,FH_FILELEN(A3)
  1193.     MOVE.L    D3,D0
  1194.     MOVEM.L    (A7)+,D3-D4/A2-A3
  1195.     DOSRTS
  1196.  
  1197. ; let the program believe that it wrote into the console
  1198.  
  1199. .fake_output:
  1200.     move.l    D3,D0        ; length written
  1201.     DOSRTS
  1202.  
  1203. ; Kills write buffer (no more buffered write on this file)
  1204. ; <A1: file handle
  1205.  
  1206. BlockBufferedWrite:
  1207.     cmp.l    #MODE_NEWFILE,FH_OPENMODE(A1)
  1208.     beq.b    .killit
  1209.     rts
  1210. .killit:
  1211.     movem.l    D0-D1/A0-A1,-(A7)
  1212.  
  1213.     move.l    FH_WRITEBUFPTR(A1),D0
  1214.     beq.b    .exit        ; no write buffer
  1215.  
  1216.     move.l    D0,D1
  1217.     move.l    FH_WRITEBUFLEN(A1),D0
  1218.     move.l    D1,A1
  1219.  
  1220.     bsr    ForeignFreeMem
  1221.  
  1222. .exit:
  1223.     movem.l    (A7)+,D0-D1/A0-A1
  1224.  
  1225.     clr.l    FH_WRITEBUFPTR(A1)
  1226.     rts
  1227.  
  1228. ;free allocated structure
  1229. _Close:
  1230.     cmp.l    #OUTPUT_HANDLER_MAGIC,D1
  1231.     beq    _DOSCLOSEMAGIC
  1232.     tst.l    D1
  1233.     beq    _DOSCLOSENULL
  1234.     BPTR2APTR    D1        ; APTR conversion (JOTD)
  1235.     move.l    D1,A1
  1236.     APTR2BPTR    D1        ; BCPL conversion (JOTD)
  1237.  
  1238.     move.l    FH_WRITEBUFPTR(A1),D0
  1239.     beq.b    _UnLock        ; no write buffer
  1240.     bsr    FlushWrite        ; write flush just before closing
  1241.  
  1242.     move.l    D1,-(A7)
  1243.     move.l    D0,D1
  1244.     move.l    FH_WRITEBUFLEN(A1),D0
  1245.     move.l    D1,A1
  1246.  
  1247.     bsr    ForeignFreeMem
  1248.  
  1249.     move.l    (A7)+,D1
  1250.  
  1251. _UnLock:
  1252.     tst.l    D1
  1253.     beq    _DOSCLOSENULL
  1254.  
  1255.     BPTR2APTR    D1        ; APTR conversion (JOTD)
  1256.     MOVE.L    D1,A1
  1257.     MOVE.L    FH_ALLOCLEN(A1),D0
  1258.  
  1259.     bsr    ForeignFreeMem
  1260.  
  1261.     moveq.l    #DOSTRUE,D0
  1262.     DOSRTS
  1263.  
  1264. _DOSCLOSENULL:
  1265.     moveq.l    #0,D0
  1266.     DOSRTS
  1267.  
  1268. _DOSCLOSEMAGIC:
  1269.     moveq.l    #DOSTRUE,D0
  1270.     DOSRTS
  1271.  
  1272. _Seek:
  1273.     BPTR2APTR    D1        ; APTR conversion (JOTD)
  1274.     MOVE.L    D1,A1
  1275.  
  1276.     ; some stuff for files opened in write mode
  1277.     ; (I don't think OSEmu handles Seek on write files but...)
  1278.  
  1279.     bsr    FlushWrite        ; will flush buffer if MODE_NEWFILE
  1280.     bsr    BlockBufferedWrite    ; no more buffered write
  1281.  
  1282.     CMP.L    #OFFSET_BEGINNING,D3
  1283.     BEQ.S    .BEGM
  1284.     CMP.L    #OFFSET_END,D3
  1285.     BEQ.S    .ENDM
  1286.     CMP.L    #OFFSET_CURRENT,D3
  1287.     BEQ.S    .CURM
  1288. .ERR    MOVEQ.L    #-1,D0
  1289.     move.l    #ERROR_SEEK_ERROR,D1
  1290.     bsr    _SetIoErr
  1291. .exit
  1292.     DOSRTS
  1293.  
  1294. .CURM
  1295.     MOVE.L    FH_CURRENTPOS(A1),D0
  1296.     MOVE.L    D0,D1
  1297.     ADD.L    D2,D1
  1298.     CMP.L    FH_FILELEN(A1),D1
  1299.     BHI.S    .ERR
  1300.     MOVE.L    D1,FH_CURRENTPOS(A1)
  1301.     bra.b    .exit
  1302.  
  1303. .ENDM    MOVE.L    FH_CURRENTPOS(A1),D0
  1304.     MOVE.L    FH_FILELEN(A1),D1
  1305.     ADD.L    D2,D1
  1306.     CMP.L    FH_FILELEN(A1),D1
  1307.     BHI.S    .ERR
  1308.     MOVE.L    D1,FH_CURRENTPOS(A1)
  1309.     bra.b    .exit
  1310.  
  1311. .BEGM    MOVE.L    FH_CURRENTPOS(A1),D0
  1312.     MOVE.L    D2,D1
  1313.     CMP.L    FH_FILELEN(A1),D1
  1314.     BHI.S    .ERR
  1315.     MOVE.L    D1,FH_CURRENTPOS(A1)
  1316.     bra.b    .exit
  1317.  
  1318. ; internal buffer flush
  1319. ; <A1: filehandle pointer
  1320.  
  1321. FlushWrite:
  1322.     cmp.l    #MODE_NEWFILE,FH_OPENMODE(A1)
  1323.     bne.b    .noflush
  1324.  
  1325.     movem.l    D0-A6,-(A7)
  1326.     move.l    A1,A3        ; filehandle
  1327.  
  1328.     move.l    FH_WRITEBUFPOS(A3),D0    ; length
  1329.     beq.b    .end        ; 0 length no need to flush
  1330.  
  1331.     LEA.L    FH_FILENAME(A3),A0    ; name
  1332.     MOVE.L    FH_WRITEBUFPTR(A3),A1    ; buffer
  1333.     MOVE.L    FH_WRITESTARTPOS(A3),D1    ; offset
  1334.  
  1335.     ; resets bufferization parameters
  1336.  
  1337.     clr.l    FH_WRITEBUFPOS(A3)
  1338.     clr.l    FH_WRITESTARTPOS(A3)
  1339.  
  1340.     ; write the file chunk
  1341.  
  1342.     move.l    _RESLOAD(pc),a5
  1343.     jsr    (resload_SaveFileOffset,a5)
  1344.  
  1345. .end
  1346.     movem.l    (A7)+,D0-A6
  1347. .noflush
  1348.     rts
  1349.  
  1350. ; Added by JOTD. Now Flashback works
  1351. ; <D2: info structure to fill in
  1352. ; >D0: TRUE if success (which is always the case)
  1353.  
  1354. _Info:
  1355.     movem.l    A1,-(A7)
  1356.     move.l    D2,A1
  1357.  
  1358.     move.l    #0,(id_NumSoftErrors,A1)    ; no errors!
  1359.     move.l    #0,(id_UnitNumber,A1)        ; unit 0 should be OK
  1360.     move.l    #ID_VALIDATED,(id_DiskState,A1)    ; disk validated
  1361.     move.l    #10000,(id_NumBlocks,A1)    ; number of blocks = 500 Megs
  1362.     move.l    #ID_DOS_DISK,(id_DiskType,A1)    ; disk type: OFS
  1363.     move.l    #0,(id_VolumeNode,A1)        ; zero this entry. it sucks but...
  1364.     move.l    #0,(id_InUse,A1)        ; not in use
  1365.  
  1366.     movem.l    (A7)+,A1
  1367.     moveq.l    #DOSTRUE,D0        ; returns TRUE (success)
  1368.     DOSRTS
  1369.  
  1370. _Delay:            ; added by JOTD
  1371.     tst.l    D1
  1372.     beq.b    .exit
  1373. .loop
  1374.     bsr    _waitvb
  1375.     subq.l    #1,D1
  1376.     bne.b    .loop
  1377. .exit
  1378.     rts
  1379.  
  1380. ; make as if the clock was not set
  1381.  
  1382. DATESTAMP:
  1383.     move.l    D1,A0
  1384.     clr.l    (A0)+
  1385.     clr.l    (A0)+
  1386.     clr.l    (A0)
  1387.     move.l    D1,D0
  1388.     rts
  1389.  
  1390. **************************************************************************
  1391. *   FILE MANAGEMENT FUNCTIONS                                            *
  1392. **************************************************************************
  1393.  
  1394. ;filehandle represents the following structure (do not try to access it!):
  1395. ;0-allocated len
  1396. ;4-total filelength
  1397. ;8-pointer in file
  1398. ;$c-openmodus
  1399. ;$10-filename
  1400.  
  1401. ;if $10 of filehandle is a : its the volumelock
  1402. ;atm: 0.L-$1000 len, 4.W-# of file in examine/exnext (-1:invalid), 
  1403. ;6.W-MAX# OF FILES, 8.L-pointer in table, $c.L-openmode
  1404.  
  1405. _Lock:
  1406.     MOVEM.L    D4-D5/A2-A5,-(A7)
  1407.     MOVE.L    D1,A3
  1408.     MOVE.L    #FH_FILENAME,D4            ;HEADERLEN
  1409.     TST.B    (A3)
  1410.     BEQ.B    .ERR        ; empty filename, error
  1411. .1    ADDQ.L    #1,D4
  1412.     TST.B    (A3)+
  1413.     BNE.S    .1
  1414.     ADDQ.L    #7,D4            ;NEXT $8-BOUNDARY
  1415.     AND.L    #$FFFFFFF8,D4
  1416.     MOVE.L    D1,D5            ;^NAME
  1417.     MOVE.L    D4,D0            ;ALLOC. LENGTH
  1418.     MOVE.L    #MEMF_CLEAR,D1
  1419.     BSR.W    ForeignAllocMem
  1420.     TST.L    D0
  1421.     BEQ.S    .ERR
  1422.  
  1423.     MOVE.L    D0,A3
  1424.     MOVE.L    D4,FH_ALLOCLEN(A3)            ;ALLOC. LENGTH
  1425.     MOVE.L    D2,FH_OPENMODE(A3)        ;OPENMODE
  1426.     CLR.L    FH_CURRENTPOS(A3)            ;INFILE-POINTER TO 0
  1427.  
  1428.     ; JOTD: devicename strip cleaned up
  1429.  
  1430.     move.l    D5,A0
  1431.     bsr    SetCurrentDir
  1432.     lea    FH_FILENAME(A3),A4
  1433. .namecopy
  1434.     move.b    (A0)+,(A4)+
  1435.     bne.b    .namecopy
  1436.     
  1437.     lea    FH_FILENAME(A3),A4
  1438.     tst.b    (A4)
  1439.     beq.b    .VOLUMELOCK    ; lock root directory
  1440.  
  1441.  
  1442.     ;--------------------------------------------------
  1443.     IFD    HARRYOLDCODE
  1444.     LEA.L    FH_FILENAME(A3),A4        ;TRANS FILENAME
  1445.     MOVE.L    D5,A5
  1446. .2    MOVE.B    (A5)+,(A4)        ; remove the volume name
  1447.     BEQ.S    .4
  1448.     CMP.B    #':',(A4)
  1449.     BNE.S    .3
  1450.  
  1451.     TST.B    (A5)
  1452.     BEQ.S    .VOLUMELOCK    ; lock root directory
  1453.  
  1454.     LEA.L    FH_FILENAME-1(A3),A4
  1455. .3    ADDQ.W    #1,A4
  1456.     BRA.S    .2
  1457. .4
  1458.     ENDC
  1459.     ;--------------------------------------------------
  1460.  
  1461.  
  1462.     ;CHECK IF FILE EXISTS
  1463.     ;(we need to know if we locked a file or a directory)
  1464.     ;due to WHDLoad limitations, we've got to work around
  1465.     ;the directory existence test problem
  1466.  
  1467.     LEA.L    FH_FILENAME(A3),A0        ;filename
  1468.     move.l    _RESLOAD(PC),a1
  1469.     jsr    (resload_GetFileSize,a1)
  1470.     MOVE.L    D0,FH_FILELEN(A3)
  1471.  
  1472.     TST.L    D0
  1473.     BEQ.S    .TRYDIR            ;GetFileSize failed, maybe it's a directory...
  1474.     MOVE.L    A3,D0
  1475. .END
  1476.     MOVEM.L    (A7)+,D4-D5/A2-A5
  1477.     APTR2BPTR    D0        ; BCPL conversion (JOTD)
  1478.     DOSRTS
  1479.  
  1480. .ERR    MOVEQ.L    #0,D0
  1481.     BRA.S    .END
  1482.  
  1483. ; directory locked: rootdir locked
  1484.  
  1485. .VOLUMELOCK
  1486.     MOVE.L    FH_ALLOCLEN(A3),D0    ;free mem because we need a larger area
  1487.     MOVE.L    A3,A1            ; JOTD: bugfix: changed D1 to A1
  1488.  
  1489.     bsr    ForeignFreeMem
  1490.  
  1491.     MOVE.L    #$1000,D0
  1492.     MOVE.L    #MEMF_CLEAR,D1    ; MEMF_CHIP removed
  1493.     BSR.W    ForeignAllocMem
  1494.     TST.L    D0
  1495.     BEQ.W    .ERR
  1496.     MOVE.L    D0,A3
  1497. ;;    MOVE.B    #':',FH_FILENAME(A3)    ; addressing error bug: ':' instead of #':'
  1498.     CLR.B    FH_FILENAME(A3)        ; addressing error bug: ':' instead of #':'
  1499.     MOVE.L    D2,FH_OPENMODE(A3)
  1500.     MOVE.W    #-2,FH_FILELEN(A3)    ; directory
  1501.                     ;8(A3) is already clear due MEMF_CLEAR
  1502.     MOVE.L    #$1000,FH_ALLOCLEN(A3)
  1503.     BRA.W    .END
  1504.  
  1505. .TRYDIR:
  1506.     LEA.L    FH_FILENAME(A3),A0        ;filename
  1507.     move.l    _RESLOAD(PC),a2
  1508.     lea    .smallbuf(pc),A1
  1509.     moveq.l    #4,D0        ; small buffer
  1510.     jsr    (resload_ListFiles,a2)
  1511.  
  1512.     tst.l    D1
  1513.     BNE.S    .LOCKFAILED        ; directory not found
  1514.  
  1515.     ; directory found here
  1516.  
  1517.     MOVE.L    FH_ALLOCLEN(A3),D0    ;free mem because we need a larger area
  1518.     MOVE.L    A3,A1            ; JOTD: bugfix: changed D1 to A1
  1519.  
  1520.     bsr    ForeignFreeMem
  1521.  
  1522.     MOVE.L    #$1000,D0
  1523.     MOVE.L    #MEMF_CLEAR,D1    ; MEMF_CHIP removed
  1524.     BSR.W    ForeignAllocMem
  1525.     TST.L    D0
  1526.     BEQ.S    .ERR
  1527.     MOVE.L    D0,A3
  1528.  
  1529.     ; copy directory name
  1530.  
  1531.     lea    FH_FILENAME(A3),A5
  1532.     move.l    A0,A4    ; save A0
  1533.  
  1534.     move.l    D5,A0
  1535.     bsr    SetCurrentDir
  1536. .copy
  1537.     move.b    (A0)+,(A5)+
  1538.     bne.b    .copy
  1539.  
  1540.     move.l    A4,A0    ; restore A0
  1541.  
  1542.     MOVE.L    D2,FH_OPENMODE(A3)
  1543.     MOVE.W    #-2,FH_FILELEN(A3)    ; -2 for directory
  1544.  
  1545.                     ;8(A3) is already clear due MEMF_CLEAR
  1546.     MOVE.L    #$1000,FH_ALLOCLEN(A3)
  1547.     BRA.W    .END
  1548.  
  1549. .smallbuf:
  1550.     blk.l    10,0
  1551.  
  1552. .LOCKFAILED
  1553.     MOVEQ.L    #0,D0
  1554.     ; sets IoErr()
  1555.     move.l    #ERROR_DIR_NOT_FOUND,D1
  1556.     BSR    _SetIoErr
  1557. .FREEMEM
  1558.     MOVE.L    D0,D5
  1559.     MOVE.L    FH_ALLOCLEN(A3),D0
  1560.     MOVE.L    A3,A1            ; bugfix there too
  1561.  
  1562.     bsr    ForeignFreeMem
  1563.  
  1564.     MOVE.L    D5,D0
  1565.     BRA.W    .END
  1566.  
  1567. ; OpenFromLock() acts just as DupLock(), but I will have to change this
  1568. ; when we change filehandle structure to match the real one
  1569. ; < D1: lock
  1570. ; > D0: lock copy
  1571.  
  1572. _OpenFromLock:
  1573.  
  1574. _DupLock:
  1575.     TST.L    D1
  1576.     BEQ.S    .ROOTLOCK
  1577.  
  1578.     BPTR2APTR    D1
  1579.  
  1580.     MOVE.L    D1,-(A7)
  1581.     MOVE.L    D1,A0
  1582.     MOVE.L    FH_ALLOCLEN(A0),D0
  1583.     MOVE.L    #MEMF_CLEAR,D1
  1584.     BSR.W    ForeignAllocMem
  1585.     MOVE.L    (A7)+,A0
  1586.     TST.L    D0
  1587.     BEQ.S    .ERR
  1588.     MOVE.L    D0,A1
  1589.     MOVE.L    FH_ALLOCLEN(A0),D1
  1590.     SUBQ.L    #1,D1
  1591. .1    MOVE.B    (A0)+,(A1)+
  1592.     DBF    D1,.1
  1593. .EXIT
  1594.     APTR2BPTR    D0
  1595.     DOSRTS
  1596.  
  1597. .ERR    MOVEQ.L    #0,D0
  1598.     DOSRTS
  1599.  
  1600. ; duplicate from no source
  1601.  
  1602. .ROOTLOCK
  1603.     MOVE.L    #FH_FILENAME+10,D0
  1604.     MOVE.L    #MEMF_CLEAR,D1
  1605.     BSR.W    ForeignAllocMem
  1606.     TST.L    D0
  1607.     BEQ.S    .ERR
  1608.     MOVE.L    D0,A0
  1609.     MOVE.L    #FH_FILENAME+10,FH_ALLOCLEN(A0)
  1610.     move.l    #-2,FH_FILELEN(A1)    ; directory
  1611.     bra.b    .EXIT
  1612.  
  1613. ; Examine next directory entry
  1614. ; < D1: lock
  1615.  
  1616. _ExNext:
  1617.     MOVEM.L    A2-A3,-(A7)
  1618.     BPTR2APTR    D1
  1619.  
  1620.     move.l    D1,A3
  1621.     move.l    FH_CURRENTPOS(A3),A2
  1622.     tst.b    (A2)
  1623.     beq.b    .nomorefiles
  1624.     bsr    ExamineOneFile
  1625.     moveq.l    #DOSTRUE,D0        ; ok
  1626. .exit
  1627.     MOVEM.L    (A7)+,A2-A3
  1628.     DOSRTS
  1629.  
  1630. .nomorefiles
  1631.     move.l    #ERROR_NO_MORE_ENTRIES,last_io_error    ; not really an error...
  1632.     moveq.l    #0,D0
  1633.     bra.b    .exit
  1634.  
  1635. ; < A3: filehandle
  1636. ; > D0: 0 if OK, -1 if error
  1637.  
  1638. ExamineOneFile:
  1639.     move.l    FH_CURRENTPOS(A3),A1    ; current file pointer
  1640.     lea    FH_FILENAME(A3),A0    ; current directory lock name
  1641.  
  1642.     lea    .temp_buffer(pc),A2
  1643.     bsr    _ADDPART
  1644.  
  1645.     lea    .temp_buffer(pc),A0
  1646.     MOVE.L    _RESLOAD(PC),A2
  1647.     jsr    (resload_GetFileSize,a2)
  1648.     ADDQ.L    #1,FH_FILELEN(A3)    ; 1 more file
  1649.     MOVE.L    D2,A2        ; FIB
  1650.  
  1651.     TST.L    D0
  1652.     BNE.W    .isfile    ; don't care about the errors (dir)
  1653.     MOVE.L    #ST_USERDIR,fib_DirEntryType(A2)    ; directory
  1654.     MOVE.L    #ST_USERDIR,fib_EntryType(A2)    ; directory
  1655.     bra.b    .fillname
  1656. .isfile
  1657.  
  1658.     MOVE.L    D0,fib_Size(A2)
  1659.     MOVE.L    #2,(A2)    
  1660.     MOVE.L    #ST_FILE,fib_DirEntryType(A2)    ; regular file
  1661.     MOVE.L    #ST_FILE,fib_EntryType(A2)    ; regular file
  1662.     SUBQ.L    #1,D0
  1663.     LSR.L    #8,D0            ;ASSUMED FFS
  1664.     LSR.L    #1,D0
  1665. ;    DIVU    #$1E8,D0        ;WOULD BE OFS
  1666.     ADDQ.L    #1,D0
  1667.     MOVE.L    D0,fib_NumBlocks(A2)
  1668. .fillname:
  1669.     move.l    FH_CURRENTPOS(A3),A0    ; current file pointer
  1670.     LEA.L    fib_FileName(A2),A1
  1671. .COPYFILENAME2
  1672.     MOVE.B    (A0)+,(A1)+
  1673.     TST.B    -1(A0)
  1674.     BNE.S    .COPYFILENAME2
  1675.  
  1676.     MOVE.L    A0,FH_CURRENTPOS(A3)        ; UPDATE FILENAME POINTER
  1677.     moveq.l    #0,D0        ; was OK
  1678.     RTS
  1679. .ERR
  1680.     MOVEQ.L    #-1,D0
  1681.     rts
  1682. .temp_buffer:
  1683.     blk.b    256,0
  1684.  
  1685. ; added by JOTD, utility function,
  1686. ; could be plugged to the read AddPart
  1687. ; if anyone needs it
  1688.  
  1689. ; < A0: dirname
  1690. ; < A1: filename
  1691. ; > A2: dirname/filename
  1692.  
  1693. _ADDPART:
  1694.     movem.l    A0-A2,-(A7)
  1695.     clr.b    (A2)
  1696.  
  1697.     tst.b    (A0)
  1698.     beq.b    .cp_filename    ; no dirname
  1699.  
  1700. .cp_dirname
  1701.     move.b    (A0)+,(A2)+
  1702.     bne.b    .cp_dirname
  1703.  
  1704.     subq.l    #1,A2
  1705.  
  1706.     cmp.b    #'/',(-1,A2)    ; ends by /
  1707.     beq.b    .cp_filename
  1708.  
  1709.     move.b    #'/',(A2)+
  1710.  
  1711. .cp_filename
  1712.     move.b    (A1)+,(A2)+
  1713.     bne.b    .cp_filename
  1714.  
  1715.     movem.l    (A7)+,A0-A2
  1716.     RTS
  1717.  
  1718. ; < D1: lock
  1719. ; < D2: file info block
  1720.  
  1721. _Examine:
  1722.     MOVEM.L    A2-A3,-(A7)
  1723.  
  1724.     BPTR2APTR    D1
  1725.  
  1726.     MOVE.L    D1,A3
  1727.  
  1728.     cmp.w    #-2,FH_FILELEN(A3)
  1729.     bne.b    .ONEFILE
  1730.  
  1731. .DIRECTORY:
  1732. .VOLUME:
  1733.     ; volume (current dir)/dir lock
  1734.     ; skip the directory name
  1735.  
  1736.     LEA.L    FH_FILENAME(A3),A2
  1737. .zerohunt
  1738.     tst.b    (A2)+
  1739.     bne.b    .zerohunt
  1740.     move.l    A2,FH_DIRLISTSTART(A3)
  1741.     LEA.L    FH_FILENAME(A3),A1
  1742.     move.l    A2,A4
  1743.     sub.l    A1,A4
  1744.     
  1745.     ; clear the filelist zone
  1746.  
  1747.     MOVE.L    #$1000-FH_FILENAME-1,D0
  1748.     sub.l    A4,D0
  1749.     move.l    D0,D1        ; save buffer length
  1750. .CLR1    CLR.B    (A2)+
  1751.     DBF    D0,.CLR1
  1752.                     
  1753.     MOVE.L    D1,D0            ; buffer max length
  1754.     LEA.L    FH_FILENAME(A3),A0    ; GET FILEDIR
  1755.     MOVE.L    FH_DIRLISTSTART(A3),A1    ; buffer
  1756.     move.l    _RESLOAD(pc),a2
  1757.  
  1758.     jsr    (resload_ListFiles,a2)
  1759.  
  1760.     TST.W    D0
  1761.     BEQ.W    .ERR
  1762.  
  1763.     MOVE.L    FH_DIRLISTSTART(A3),FH_CURRENTPOS(A3)    ; init file pointer with first file of dir
  1764.  
  1765.     ; fill file info block structure fields (dir type, name)
  1766.  
  1767.     move.l    D2,A0
  1768.     move.l    #ST_USERDIR,fib_DirEntryType(A0)    ; directory
  1769.     move.l    #ST_USERDIR,fib_EntryType(A0)    ; directory
  1770.     LEA    fib_FileName(A0),A1    ; copy name
  1771.     LEA    FH_FILENAME(A3),A0
  1772. .COPYFILENAME2
  1773.     MOVE.B    (A0)+,(A1)+
  1774. ;;    TST.B    -1(A0)        ; JOTD: useless
  1775.     BNE.S    .COPYFILENAME2
  1776.  
  1777.     MOVEM.L    (A7)+,A2-A3
  1778.     RTS
  1779.  
  1780.  
  1781. .ONEFILE
  1782.     lea    FH_FILENAME(A3),a0        ;filename
  1783.     move.l    _RESLOAD(PC),a2
  1784.     jsr    (resload_GetFileSize,a2)
  1785.     TST.L    D0
  1786.     BEQ.S    .ERR
  1787.     MOVE.L    D2,A2
  1788.     MOVE.L    D0,fib_Size(A2)
  1789.     MOVE.L    #2,(A2)    
  1790.     MOVE.L    #ST_FILE,fib_DirEntryType(A2)
  1791.     MOVE.L    #ST_FILE,fib_EntryType(A2)    ; added by JOTD, Sensible Soccer CD32 v1.2
  1792.     MOVE.L    #$F0,fib_Protection(A2)        ; added by JOTD, File rwxd
  1793.     LSR.L    #8,D0            ;ASSUMED FFS
  1794.     LSR.L    #1,D0
  1795. ;    DIVU    #$1E8,D0        ;WOULD BE OFS
  1796.     ADDQ.L    #1,D0
  1797.     MOVE.L    D0,fib_NumBlocks(A2)    
  1798.     LEA.L    FH_FILENAME(A3),A0
  1799.     LEA.L    fib_FileName(A2),A1
  1800. .COPYFILENAME
  1801.     MOVE.B    (A0)+,(A1)+
  1802. ;;    TST.B    -1(A0)        ; JOTD: useless
  1803.     BNE.S    .COPYFILENAME
  1804.     MOVEQ.L    #DOSTRUE,D0
  1805.     MOVEM.L    (A7)+,A2-A3
  1806.     RTS
  1807.  
  1808. .ERR        pea    _LVOExamine
  1809.         pea    _dosname
  1810.         bra    _emufail
  1811.  
  1812. ; Computes basename from full name (JOTD)
  1813. ; < A0: name
  1814. ; > A0: name's file part
  1815. ; kind of strrchr with '/' char
  1816. ; unused at the moment, but works
  1817.     ifeq    1
  1818. BaseName:
  1819.     movem.l    D0,-(A7)
  1820.     ; first count string length
  1821.     moveq.l    #0,D0        
  1822. .loop1
  1823.     tst.b    (A0,D0.L)
  1824.     beq.b    .countend
  1825.     addq.l    #1,D0
  1826.     bra.b    .loop1
  1827. .countend
  1828.  
  1829. .loop2
  1830.     cmp.b    #'/',(A0,D0.L)
  1831.     beq.b    .found
  1832.     cmp.b    #':',(A0,D0.L)
  1833.     beq.b    .found
  1834.     dbf    D0,.loop2
  1835.     bra.b    .exit
  1836. .found
  1837.     lea    1(A0,D0.L),A0
  1838. .exit
  1839.     movem.l    (A7)+,D0
  1840.     rts
  1841.     endif
  1842.  
  1843. ; < A0: name
  1844. ; > A0: name with current dir added
  1845.  
  1846. SetCurrentDir:
  1847.     movem.l    A3,-(A7)
  1848.  
  1849.     move.l    $4.W,A3
  1850.     move.l    ThisTask(A3),A3
  1851.     tst.l    pr_CurrentDir(A3)
  1852.     beq.b    .end        ; no need to append path
  1853.  
  1854.     ; the directory was changed
  1855.     ; we need to check if the path is relative or
  1856.     ; absolute
  1857.  
  1858.     movem.l    D0-D1/A0-A2,-(A7)
  1859.     moveq.l    #0,D0
  1860. .colonloop
  1861.     tst.b    (A0,D0.L)
  1862.     beq.b    .relative    ; colon not found: relative path
  1863.     cmp.b    #':',(A0,D0.L)
  1864.     beq.b    .absolute
  1865.     addq.l    #1,D0
  1866.     bra.b    .colonloop
  1867. .relative
  1868.     ; this is untested!
  1869.  
  1870.     ; add the current dirname at start
  1871.  
  1872.     move.l    pr_CurrentDir(A3),D0
  1873.     BPTR2APTR    D0        ; converts to APTR
  1874.     move.l    A0,A1            ; filename    
  1875.     move.l    D0,A0
  1876.     lea    (FH_FILENAME,A0),A0    ; directory name
  1877.     lea    .namebuffer(pc),A2
  1878.     bsr    _ADDPART
  1879.     move.l    A2,8(A7)    ; will be in A0 when registers are restored
  1880. .absolute:            ; absolute path, the current directory has no effect
  1881.     movem.l    (A7)+,D0-D1/A0-A2
  1882. .end:
  1883.     bsr    RemoveColonFromName
  1884.     movem.l    (A7)+,A3
  1885.     rts
  1886.  
  1887. .namebuffer:
  1888.     blk.b    256,0
  1889.  
  1890. ; Removes volumename: prefix if any (only changes pointer)
  1891. ; < A0: name
  1892. ; > A0: name without colon
  1893. ; kind of strchr with ':' char
  1894.  
  1895. RemoveColonFromName:
  1896.     movem.l    D0/A1,-(A7)
  1897.     move.l    A0,A1        ; save A0
  1898. .loop
  1899.     move.b    (A0)+,D0
  1900.     beq.b    .endofstring
  1901.     cmp.b    #':',D0
  1902.     bne.b    .loop
  1903. .exit
  1904.     movem.l    (A7)+,D0/A1
  1905.     rts
  1906.  
  1907. ; colon was not found: restore original string
  1908.  
  1909. .endofstring:
  1910.     move.l    A1,A0        ; original A0
  1911.     bra.b    .exit
  1912.  
  1913. ; added by JOTD (needed by SlamTilt)
  1914.  
  1915. _ExamineFH:
  1916.     MOVEM.L    D3/A3,-(A7)
  1917.  
  1918.     BPTR2APTR    D1
  1919.  
  1920.     MOVE.L    D1,A3
  1921.     MOVE.L    D2,D3            ;output struct
  1922.     LEA.L    FH_FILENAME(A3),A0        ;NAME
  1923.     move.l    A0,D1
  1924.     move.l    #MODE_OLDFILE,D2
  1925.     bsr    _Open    
  1926.     move.l    D0,-(A7)
  1927.  
  1928.     move.l    D3,D2
  1929.     move.l    D0,D1            ;filehandle!
  1930.     bsr    _Examine
  1931.  
  1932.     move.l    (A7)+,D1
  1933.     bsr    _Close
  1934.  
  1935.     MOVEM.L    (A7)+,D3/A3
  1936.     RTS
  1937.  
  1938. _IsInteractive:
  1939.     moveq    #0,D0
  1940.     cmp.l    #OUTPUT_HANDLER_MAGIC,D1
  1941.     bne.b    .noint
  1942.     moveq    #DOSTRUE,D0        ; interactive
  1943. .noint
  1944.     rts
  1945.  
  1946. ; CurrentDir
  1947. ; < D1: new dirlock
  1948. ; > D0: old dirlock
  1949.  
  1950. _CurrentDir:
  1951.     movem.l    D2/A2/A6,-(A7)
  1952.     move.l    D1,D2
  1953.  
  1954.     sub.l    A1,A1
  1955.     move.l    $4.W,A6
  1956.     JSRLIB    FindTask    ; find ourselves
  1957.     move.l    D0,A2
  1958.     move.l    pr_CurrentDir(A2),D0        ; old lock to return
  1959.  
  1960.     tst.l    D2
  1961.     beq.b    .root        ; NULL lock: root directory
  1962.  
  1963.     move.l    D2,A0        ; save dir pointer
  1964.     BPTR2APTR    D2    ; APTR conversion
  1965.  
  1966.     ; check if it's a file: Cruise For A Corpse tries
  1967.     ; to CurrentDir() with a file lock!
  1968.  
  1969.     move.l    D2,A1
  1970.     tst.l    FH_FILELEN(A1)
  1971.     bpl.b    .file
  1972.  
  1973.     ; it's a directory: ok to change lock
  1974.  
  1975.     move.l    A0,D2        ; restore BPTR lock
  1976. .root
  1977.     move.l    D2,pr_CurrentDir(A2)    ; sets new dirlock as current directory
  1978. .file
  1979.     movem.l    (A7)+,D2/A2/A6
  1980.     DOSRTS
  1981.  
  1982. ; < D1: lock
  1983. ; > D0: lock of parent or NULL
  1984.  
  1985. _ParentDir:
  1986.     ; first duplicates the lock
  1987.  
  1988.     bsr    _DupLock
  1989.  
  1990.     move.l    D0,A1
  1991.     BPTR2APTR    A1
  1992.     lea    FH_FILENAME(A1),A1    ; pointer on filename
  1993.     move.l    A1,A0
  1994. .loop1
  1995.     tst.b    (A0)+
  1996.     bne.b    .loop1
  1997.     ; reached end of filename, now reverse to find first '/' in name
  1998.  
  1999. .loop2
  2000.     cmp.b    #'/',-(A0)
  2001.     beq.b    .slashfound
  2002.     cmp.l    A0,A1
  2003.     bne.b    .loop2
  2004.  
  2005.     ; met start of filename: parent not found: returns lock on root path
  2006.     ; (should return NULL but...)
  2007.  
  2008.     move.l    D0,A1
  2009.     BPTR2APTR    A1
  2010.     lea    FH_FILENAME(A1),A1    ; pointer on filename
  2011.     move.b    #':',(A1)+
  2012.     clr.b    (A1)    
  2013.     bra.b    .out
  2014.  
  2015. .slashfound
  2016.     ; slash found: replaces by 0
  2017.  
  2018.     clr.b    (A0)
  2019.     
  2020.     ; returns new lock
  2021.  
  2022. .out
  2023.     DOSRTS
  2024.